
// Created by ziya on 2021/9/6.
//

/**
 * 实现逻辑: 开发部门与测试部门之间,开发部门开发完了,测试部门闲了,就可以开始测试
 * 使用CAS+mutex+cond解决(hotspot就是这样实现的)
 */

#include "../common.h"
#include "../lib/Atomic.h"

#include <pthread.h>

// 测试部门是否已准备好
int is_ready = 0;

pthread_mutex_t mutex;
pthread_cond_t cond;

void* thread_fun_1(void* arg) {
    WRITE("[开发部门] 已开发完成,等待测试部门测试\n");

    for (;;) {
        if (1 == Atomic::cmpxchg(0, &is_ready, 1)) {
            break;
        } else {
            WRITE("[开发部门] 检测到测试还未准备就绪\n");

            sleep(1);
        }
    }

    WRITE("[开发部门] 检测到测试已准备就绪,唤醒\n");

    pthread_cond_signal(&cond);

    return 0;
}

void* thread_fun_2(void* arg) {
    // 模拟测试部门5S很忙
    sleep(5);

    WRITE("[测试部门] 我忙完了,开发大佬\n");

    pthread_mutex_lock(&mutex);

    is_ready = 1;

    pthread_mutex_unlock(&mutex);

    //=====
    pthread_cond_wait(&cond, &mutex);

    // 模拟测试好难
    sleep(3);

    WRITE("[测试部门] 测试完了,开发大佬\n");

    return 0;
}

int main() {
    int status;
    pthread_t tids[2];

    status = pthread_mutex_init(&mutex, NULL);
    ASSERT_ZERO(status, "pthread_mutex_init fail\n");

    status == pthread_cond_init(&cond, NULL);
    ASSERT_ZERO(status, "pthread_cond_init fail\n");

    pthread_create(&tids[0], NULL, thread_fun_1, NULL);

    pthread_create(&tids[1], NULL, thread_fun_2, NULL);

    pthread_join(tids[0], NULL);

    pthread_join(tids[1], NULL);

    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&mutex);

    INFO_PRINT("主线程运行结束\n");

    return 0;
}